package com.wurd.test.wx.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wurd.test.config.Config;
import com.wurd.test.exception.WxException;
import com.wurd.test.wx.token.Token;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.impl.DefaultHttpRequestRetryStrategy;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.util.TimeValue;

public class TokenUtils {

    private static CloseableHttpClient client = HttpClients.custom()
            .setConnectionReuseStrategy((request, response, context) -> false)
            .setRetryStrategy(new DefaultHttpRequestRetryStrategy(3, TimeValue.ofMilliseconds(500L)))
            .build();

    public static boolean verifyToken(Token token) {
        long now = System.currentTimeMillis() / 1000;
        return token != null && (now - token.getCreateTs()) < (token.getExpiresIn() - 60);
    }

    public static JSONObject postComponentAccessToken(JSONObject preBody) throws Exception {
        HttpPost post = new HttpPost(Config.componentAccessTokenURL);
        post.setEntity(new StringEntity(preBody.toJSONString()));
        HttpEntity resEntity = client.execute(post).getEntity();
        String res = EntityUtils.toString(resEntity);
        JSONObject obj = JSON.parseObject(res);
        String tokenStr = obj.getString("component_access_token");
        if (tokenStr == null) {
            throw new WxException(res);
        }
        return obj;
    }

    public static JSONObject postPreAuthCode(JSONObject preParam, JSONObject preBody) throws Exception {
        String url = Config.preAuthCodeURL + preParam.getString("component_access_token");
        HttpPost post = new HttpPost(url);
        post.setEntity(new StringEntity(preBody.toJSONString()));
        HttpEntity resEntity = client.execute(post).getEntity();
        String res = EntityUtils.toString(resEntity);
        JSONObject obj = JSON.parseObject(res);
        String tokenStr = obj.getString("pre_auth_code");
        if (tokenStr == null) {
            throw new WxException(res);
        }
        return obj;
    }

    public static JSONObject postAuthRefreshToken(JSONObject preParam, JSONObject preBody) throws Exception {
        String url = Config.authRefreshTokenURL + preParam.getString("component_access_token");
        HttpPost post = new HttpPost(url);
        post.setEntity(new StringEntity(preBody.toJSONString()));
        HttpEntity resEntity = client.execute(post).getEntity();
        String res = EntityUtils.toString(resEntity);
        JSONObject obj = JSON.parseObject(res);
        JSONObject authInfo = obj.getJSONObject("authorization_info");
        if (authInfo == null) {
            throw new WxException(res);
        }
        return authInfo;
    }

    public static JSONObject postAuthAccessToken(JSONObject preParam, JSONObject preBody) throws Exception {
        String url = Config.authAccessTokenURL + preParam.getString("component_access_token");
        HttpPost post = new HttpPost(url);
        post.setEntity(new StringEntity(preBody.toJSONString()));
        HttpEntity resEntity = client.execute(post).getEntity();
        String res = EntityUtils.toString(resEntity);
        JSONObject obj = JSON.parseObject(res);
        String accessToken = obj.getString("authorizer_access_token");
        if (accessToken == null) {
            throw new WxException(res);
        }
        return obj;
    }

    public static JSONObject postMaterialList(JSONObject preParam, JSONObject preBody) throws Exception {
        String url = Config.materialListURL + preParam.getString("access_token");
        HttpPost post = new HttpPost(url);
        post.setEntity(new StringEntity(preBody.toJSONString()));
        HttpEntity resEntity = client.execute(post).getEntity();
        String res = EntityUtils.toString(resEntity);
        JSONObject obj = JSON.parseObject(res);
        return obj;
    }

    public static JSONObject getGzhAccessToken(JSONObject preParam) throws Exception {
        StringBuilder url = new StringBuilder(Config.gzh_accessTokenURL);
        preParam.forEach((k, v) -> {
            url.append(k).append("=").append(v).append("&");
        });
        HttpGet get = new HttpGet(url.toString());
        HttpEntity resEntity = client.execute(get).getEntity();
        String res = EntityUtils.toString(resEntity);
        JSONObject obj = JSON.parseObject(res);
        String token = obj.getString("access_token");
        if (token == null) {
            throw new WxException(obj.toJSONString());
        }
        return obj;
    }

    public static JSONObject getGzhIndustry(JSONObject preParam) throws Exception {
        StringBuilder url = new StringBuilder(Config.gzh_getIndustryURL);
        preParam.forEach((k, v) -> {
            url.append(k).append("=").append(v).append("&");
        });
        HttpGet get = new HttpGet(url.toString());
        HttpEntity resEntity = client.execute(get).getEntity();
        String res = EntityUtils.toString(resEntity);
        JSONObject obj = JSON.parseObject(res);
//        String token = obj.getString("primary_industry");
//        if (token == null) {
//            throw new WxException(obj.toJSONString());
//        }
        return obj;
    }

    public static JSONObject postGzhIndustry(JSONObject preParam, JSONObject preBody) throws Exception {
        StringBuilder url = new StringBuilder(Config.gzh_postIndustryURL);
        preParam.forEach((k, v) -> {
            url.append(k).append("=").append(v).append("&");
        });
        HttpPost post = new HttpPost(url.toString());
        post.setEntity(new StringEntity(preBody.toJSONString()));
        HttpEntity resEntity = client.execute(post).getEntity();
        String res = EntityUtils.toString(resEntity);
        JSONObject obj = JSON.parseObject(res);
        return obj;
    }
}
